Skip to content

Reproduce #624 race condition via real server crash#626

Closed
tony wants to merge 2 commits intomasterfrom
issue-624-recreation
Closed

Reproduce #624 race condition via real server crash#626
tony wants to merge 2 commits intomasterfrom
issue-624-recreation

Conversation

@tony
Copy link
Copy Markdown
Member

@tony tony commented Feb 5, 2026

Summary

Related:

How it works

  1. Bumper session advances session IDs so race_test gets $1
  2. server.new_session("race_test") runs real tmux new-session → returns $1
  3. Patched fetch_objs intercepts the first list-sessions call: kills the server, starts a replacement (which gets $0)
  4. Real fetch_objs runs list-sessions against the replacement server — finds only $0
  5. fetch_obj searches for $1, doesn't find it → TmuxObjectDoesNotExist

Test plan

  • uv run pytest tests/test_server.py::test_new_session_race_condition -xvs → XFAIL
  • uv run ruff check tests/test_server.py → clean
  • uv run mypy tests/test_server.py → clean
  • uv run pytest tests/test_server.py -v → 29 passed, 1 skipped, 1 xfailed

tony added 2 commits February 5, 2026 17:18
…as strict xfail

why: The previous test looped new_session() 10 times hoping to trigger a
timing race, but the bug is deterministic in PyInstaller + Python 3.13 +
Docker environments (LD_LIBRARY_PATH contamination crashes tmux server
after new-session returns, causing list-sessions to miss the session).
what:
- Replace loop-based test with monkeypatch that intercepts neo.fetch_objs
- Return empty list on first list-sessions call, simulating stale response
- Add strict=True so XPASS signals when retry-based fix is added
- Keep real tmux new-session execution to validate integration
- Add precise type annotations matching neo.fetch_objs signature
why: Previous test monkeypatched fetch_objs to return [], bypassing all
real tmux interaction. This version exercises the full code path with
real tmux commands — only crash timing is controlled.
what:
- Kill real tmux server inside fetch_objs wrapper, start replacement
- Bumper session ensures session_id mismatch (original $1 vs replacement $0)
- All 7 code paths exercised: new-session, kill-server, replacement
  new-session, list-sessions, fetch_objs parsing, fetch_obj search,
  TmuxObjectDoesNotExist
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 45.48%. Comparing base (cb21427) to head (e88a2a8).
⚠️ Report is 166 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #626      +/-   ##
==========================================
+ Coverage   45.39%   45.48%   +0.08%     
==========================================
  Files          22       22              
  Lines        2249     2249              
  Branches      360      360              
==========================================
+ Hits         1021     1023       +2     
+ Misses       1082     1081       -1     
+ Partials      146      145       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tony
Copy link
Copy Markdown
Member Author

tony commented Apr 26, 2026

Closing — the race condition this PR reproduces no longer exists.

This PR (Mar 2026) demonstrates a server-crash race in Server.new_session() (issue #624) by patching neo.fetch_objs(list_cmd="list-sessions") to inject a server kill between new-session and the follow-up list-sessions query.

That race was fixed in #625 (released in v0.53.1, see CHANGES under libtmux 0.53.1 (2026-02-18) › "Fix race condition in new_session()"). The fix expands the -F format string in new-session -P to include all session fields and parses the output directly into a Session via parse_output(session_stdout) — eliminating the follow-up list-sessions query entirely.

As a result, the PR's test patch on fetch_objs(list_cmd="list-sessions") is unreachable. Confirmed by rebasing onto current master: test_new_session_race_condition is marked xfail(strict=True) and now triggers XPASS(strict) — pytest's signal that an "expected to fail" test is unexpectedly passing.

If you want to keep documenting this scenario for regression coverage, the test could be adapted to assert on the new code path's behavior under server crash (e.g. patching Server.cmd to fail mid-new-session). Otherwise this PR has served its purpose — the bug it documents has been fixed.

Confirmed during a 2026-04-26 batch rebase audit.

@tony tony closed this Apr 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant